<template>
	<view class="page-container">
		<!-- 查询区域 -->
		<view class="tech-card query-section">
			<view class="card-title">
				<view class="title-icon">📁</view>
				<text>网盘目录查询</text>
			</view>
			<view class="query-content">
				<el-input v-model="params.path" placeholder="请输入网盘的目录地址" class="tech-input path-input" />
				<el-button @click="getFileList" class="tech-button primary-button">
					<text>🔍 查询文件</text>
				</el-button>
			</view>
		</view>

		<!-- 配置区域 -->
		<view class="tech-card config-section">
			<view class="card-title">
				<view class="title-icon">⚙️</view>
				<text>同步配置</text>
			</view>

			<!-- 所有配置在一行 -->
			<view class="config-row">
				<view class="config-item">
					<text class="config-label">所属机构</text>
					<el-select v-model="uploadParams.sourceFrom" placeholder="请选择机构" class="tech-select" filterable>
						<el-option v-for="item in sourceFromList" :key="item" :label="item" :value="item" />
					</el-select>
				</view>

				<view class="config-item">
					<text class="config-label">选择专题</text>
					<el-select v-model="uploadParams.typeDesc" placeholder="请选择专题" class="tech-select"
						@change="(e) => { uploadParams.typeId = e }" filterable>
						<el-option v-for="item in typeOptions" :key="item.value" :label="item.label"
							:value="item.value" />
					</el-select>
				</view>

				<view class="config-item">
					<text class="config-label">关联课程</text>
					<el-select v-model="uploadParams.courseId" placeholder="请选择课程" class="tech-select"
						filterable clearable>
						<el-option v-for="item in artPPTCourse" :key="item.value" :label="item.label"
							:value="item.value" />
					</el-select>
				</view>

				<view class="config-item">
					<text class="config-label">开始位置</text>
					<el-input v-model="uploadParams.startNum" placeholder="从第几个开始" class="tech-input number-input"
						type="number" />
				</view>

				<view class="config-item">
					<text class="config-label">价格设置</text>
					<el-input v-model="uploadParams.price" placeholder="请输入价格" class="tech-input number-input"
						type="number" />
				</view>
			</view>
		</view>

		<!-- 文件列表区域 -->
		<view class="tech-card table-section">
			<view class="card-title">
				<view class="title-icon">📊</view>
				<text>文件列表</text>
				<text class="file-count" v-if="dataList.length > 0">共 {{ dataList.length }} 个文件</text>

				<!-- 操作按钮组 -->
				<view class="button-group">
					<el-button @click="confirmAsaync(false)" class="tech-button success-button">
						<text>🚀 开始同步</text>
					</el-button>
					<el-button @click="confirmFailAsaync" class="tech-button warning-button">
						<text>🔄 同步失败项</text>
					</el-button>
				</view>
			</view>

			<el-table :data="dataList" class="tech-table" size="small" :row-class-name="tableRowClassName"
				:header-cell-style="{ background: '#1a1f3a', color: '#00f0ff', fontWeight: 'bold' }"
				:key="dataList.length">
				<el-table-column type="index" label="#" width="70" align="center" />

				<el-table-column label="预览" width="100" align="center">
					<template slot-scope="scope">
						<el-image class="preview-image" :src="scope.row.thumbs.url2"
							:preview-src-list="[scope.row.thumbs.url2]" fit="cover" />
					</template>
				</el-table-column>

				<el-table-column prop="server_filename" label="文件名" min-width="250" show-overflow-tooltip />

				<el-table-column prop="fs_id" label="文件ID" width="180" show-overflow-tooltip />

				<el-table-column prop="size" label="大小" width="120" align="center" />

				<el-table-column label="状态" width="140" align="center">
					<template slot-scope="scope">
						<view class="status-tag success-tag" v-if="scope.row.status == '成功'">
							✓ {{ scope.row.statusText }}
						</view>
						<view class="status-tag duplicate-tag" v-else-if="scope.row.status == '重复'">
							⚡ 已存在
						</view>
						<view class="status-tag error-tag" v-else-if="scope.row.status == '失败'">
							✗ {{ scope.row.statusText }}
						</view>
						<view class="status-tag retry-tag" v-else-if="scope.row.status == '重试'">
							🔄 {{ scope.row.statusText }}
						</view>
						<view class="status-tag timeout-tag" v-else-if="scope.row.status == '超时'">
							⏱ {{ scope.row.statusText }}
						</view>
						<view class="status-tag warning-tag" v-else-if="scope.row.status == '超出'">
							⚠ {{ scope.row.statusText }}
						</view>
						<view class="status-tag default-tag" v-else>
							○ 未上传
						</view>
					</template>
				</el-table-column>

				<el-table-column label="操作" width="100" align="center">
					<template slot-scope="scope">
						<el-button type="text" class="action-button"
							@click="uploadParams.startNum = scope.$index + 1, confirmAsaync(true)">
							上传
						</el-button>
					</template>
				</el-table-column>
			</el-table>
		</view>

		<!-- 上传进度弹窗 -->
		<el-dialog :visible.sync="showProgressDialog" title="上传进度" width="600px" :close-on-click-modal="false"
			class="progress-dialog">
			<view class="progress-container">
				<!-- 总进度条 -->
				<view class="progress-section">
					<view class="section-title">总体进度</view>
					<el-progress :percentage="uploadPercentage" :color="uploadPercentage === 100 ? '#00ff88' : '#00f0ff'"
						:stroke-width="20" :text-inside="true"></el-progress>
					<view class="progress-text">
						{{ uploadProgress.current }} / {{ uploadProgress.total }} 个文件
					</view>
				</view>

				<!-- 统计信息 -->
				<view class="stats-section">
					<view class="stat-item success-stat">
						<view class="stat-icon">✓</view>
						<view class="stat-content">
							<view class="stat-label">成功</view>
							<view class="stat-value">{{ uploadProgress.success }}</view>
						</view>
					</view>
					<view class="stat-item duplicate-stat">
						<view class="stat-icon">⚡</view>
						<view class="stat-content">
							<view class="stat-label">重复</view>
							<view class="stat-value">{{ uploadProgress.duplicate }}</view>
						</view>
					</view>
					<view class="stat-item failed-stat">
						<view class="stat-icon">✗</view>
						<view class="stat-content">
							<view class="stat-label">失败</view>
							<view class="stat-value">{{ uploadProgress.failed }}</view>
						</view>
					</view>
					<view class="stat-item timeout-stat">
						<view class="stat-icon">⏱</view>
						<view class="stat-content">
							<view class="stat-label">超时</view>
							<view class="stat-value">{{ uploadProgress.timeout }}</view>
						</view>
					</view>
				</view>

				<!-- 当前上传信息 -->
				<view class="current-upload-section" v-if="isUploading && uploadProgress.currentFileName">
					<view class="section-title">当前上传</view>
					<view class="current-file-wrapper">
						<!-- 课件缩略图 -->
						<view class="current-file-image" v-if="uploadProgress.currentFileImage">
							<el-image :src="uploadProgress.currentFileImage" fit="cover" class="course-thumbnail"
								:preview-src-list="[uploadProgress.currentFileImage]" />
						</view>

						<view class="current-file">
							<view class="file-name">{{ uploadProgress.currentFileName }}</view>
							<view class="upload-timer" :class="{ 'near-timeout': isNearTimeout, 'timeout-warning': remainingTime <= 10 }">
								<view class="timer-label">剩余时间</view>
								<view class="timer-value">{{ remainingTimeFormatted }}</view>
								<view class="timer-bar">
									<view class="timer-bar-fill" :style="{ width: (currentUploadTime / 600 * 100) + '%' }"></view>
								</view>
							</view>
						</view>
					</view>
					<view class="timeout-hint" v-if="isNearTimeout">
						⚠️ 即将超时,超过10分钟将自动跳过
					</view>
				</view>
			</view>
		</el-dialog>
	</view>
</template>

<script>
let that
export default {
	data() {
		return {
			sourceFromList: ["创意少儿美术馆", "黑马画室", "绘画的秘密", "荔枝美术", "指尖美术", "梦马美学", "花花美术"],
			params: {
				path: '/最新的课程/62、2022年 小七老师3-9岁 （55节PPT）',
			},
			uploadParams: {
				startNum: 1,
				dataList: [],
				sourceFrom: '',
				typeDesc: '',
				typeId: '',
				price: 2,
				courseId: '',
			},
			dataList: [],
			typeOptions: [],
			totalNum: 0,
			artPPTCourse: [],
			// 进度弹窗相关
			showProgressDialog: false,
			uploadProgress: {
				total: 0,
				current: 0,
				success: 0,
				failed: 0,
				timeout: 0,
				duplicate: 0, // 重复数量
				currentFileName: '',
				currentFileImage: '', // 当前文件的缩略图
			},
			currentUploadTime: 0, // 当前文件上传时间（秒）
			uploadTimerInterval: null, // 计时器
			currentRequestAbort: null, // 用于中断当前请求
			isUploading: false, // 是否正在上传
		}
	},

	computed: {
		// 上传进度百分比
		uploadPercentage() {
			if (this.uploadProgress.total === 0) return 0
			return Math.floor((this.uploadProgress.current / this.uploadProgress.total) * 100)
		},
		// 剩余时间（秒）
		remainingTime() {
			return Math.max(0, 600 - this.currentUploadTime)
		},
		// 剩余时间格式化
		remainingTimeFormatted() {
			const minutes = Math.floor(this.remainingTime / 60)
			const seconds = this.remainingTime % 60
			return `${minutes}:${seconds.toString().padStart(2, '0')}`
		},
		// 是否接近超时（剩余30秒）
		isNearTimeout() {
			return this.remainingTime <= 30 && this.remainingTime > 0
		},
	},

	onLoad() {
		that = this
		if (uni.getStorageSync("path")) that.params.path = uni.getStorageSync("path")

		that.common.rightApi("admin/artType/list", {}).then(res => {
			res.data = res.data || []
			for (let item of res.data) {
				item.value = item.objectId
				item.label = item.name
			}
			res.data.unshift({
				value: "",
				label: "全部"
			})
			that.typeOptions = res.data
		})

		that.$http.Post("admin/artPPT/list", {
			pageSize: 20,
			pageNum: 1,
			fileType: '课程',
			searchText: '',
			isNice: false,
			status: '全部',
		}, "加载中...").then(res => {
			for (let item of res.data) {
				item.value = item.objectId
				item.label = item.title
			}
			that.artPPTCourse = res.data
		})
	},
	methods: {
		// 启动上传计时器
		startUploadTimer() {
			this.currentUploadTime = 0
			this.stopUploadTimer() // 先清除之前的计时器
			this.uploadTimerInterval = setInterval(() => {
				this.currentUploadTime++
				// 超过10分钟（600秒）自动跳过
				if (this.currentUploadTime >= 600) {
					this.handleUploadTimeout()
				}
			}, 1000)
		},

		// 停止上传计时器
		stopUploadTimer() {
			if (this.uploadTimerInterval) {
				clearInterval(this.uploadTimerInterval)
				this.uploadTimerInterval = null
			}
		},

		// 处理上传超时
		handleUploadTimeout() {
			this.stopUploadTimer()

			// 标记当前文件为超时
			let currentIndex = this.uploadParams.startNum - 1
			if (currentIndex >= 0 && currentIndex < this.dataList.length) {
				let newItem = this.dataList[currentIndex]
				newItem.status = '超时'
				newItem.statusText = '上传超时'
				this.$set(this.dataList, currentIndex, newItem)
			}

			// 更新进度统计
			this.uploadProgress.timeout++
			this.uploadProgress.current++

			// 中断当前请求（如果支持）
			if (this.currentRequestAbort) {
				this.currentRequestAbort()
				this.currentRequestAbort = null
			}

			// 继续下一个
			this.uploadParams.startNum = Number(this.uploadParams.startNum) + 1
			setTimeout(() => {
				if (this.isUploading) {
					this.confirmAsaync(false)
				}
			}, 1000)
		},

		// 初始化进度
		initProgress() {
			this.uploadProgress = {
				total: this.totalNum,
				current: 0,
				success: 0,
				failed: 0,
				timeout: 0,
				duplicate: 0,
				currentFileName: '',
				currentFileImage: '',
			}
			this.showProgressDialog = true
			this.isUploading = true
		},

		// 重置进度
		resetProgress() {
			this.stopUploadTimer()
			this.currentUploadTime = 0
			this.uploadProgress.currentFileName = ''
			this.uploadProgress.currentFileImage = ''
			this.isUploading = false
		},

		tableRowClassName({
			row,
			rowIndex
		}) {
			if (rowIndex === that.startNum) {
				return 'success-row';
			}
		},

		getFileList() {
			that.params.path = that.params.path.replace(/%2F/g, "/")
			that.uploadParams.startNum = 1
			uni.setStorageSync("path", that.params.path)
			that.$http.Post("admin/baiduFile/getBaiduFile", that.params, "查询中...").then(res => {
				that.dataList = res.data.dataList
				// 为每个文件初始化重试计数
				that.dataList.forEach(item => {
					item.retryCount = 0
				})
				that.totalNum = res.data.totalNum
			})
		},

		confirmFailAsaync(index = 0) {
			if (that.dataList.length == 0) return that.common.showToast("先获取文件")

			// 如果索引超出范围，说明已经处理完所有失败项
			if (index >= that.dataList.length) {
				that.common.showToast("失败项重新上传完成！")
				return
			}

			// 检查当前项是否存在
			let currentItem = that.dataList[index]
			if (!currentItem) {
				// 跳过不存在的项
				that.confirmFailAsaync(index + 1)
				return
			}

			// 检查是否是失败或超时的项
			if (currentItem.status == "失败" || currentItem.status == "超时") {
				that.uploadParams.startNum = index + 1
				that.$http.Post("admin/baiduFile/asayncBaiduFile", that.uploadParams, "第" + that.uploadParams
					.startNum +
					"个正在重新上传...").then(
						res => {
							let newItem = that.dataList[that.uploadParams.startNum - 1]
							newItem.status = res.status
							newItem.statusText = res.msg
							// 重置重试计数
							newItem.retryCount = 0
							that.$set(that.dataList, that.uploadParams.startNum - 1, newItem);

							that.uploadParams.startNum = Number(that.uploadParams.startNum) + 1
							that.$forceUpdate()
							that.confirmFailAsaync(index + 1)
						}).catch((err) => {
							that.uploadParams.startNum = Number(that.uploadParams.startNum)
							that.confirmFailAsaync(index)
						})
			} else {
				that.confirmFailAsaync(index + 1)
			}
		},

		confirmAsaync(isSingle = false) {
			if (that.dataList.length == 0) return that.common.showToast("先获取文件")

			// 如果是批量上传且还未开始上传，初始化进度
			if (!isSingle && !that.isUploading) {
				that.initProgress()
			}

			// 如果已经上传完所有文件
			if (that.uploadParams.startNum > that.totalNum) {
				that.resetProgress()
				that.common.showToast("上传完成！")
				return
			}

			// 获取当前文件信息
			let currentIndex = that.uploadParams.startNum - 1
			let currentFile = that.dataList[currentIndex]
			if (currentFile) {
				that.uploadProgress.currentFileName = currentFile.server_filename
				// 设置当前文件的缩略图
				if (currentFile.thumbs && currentFile.thumbs.url2) {
					that.uploadProgress.currentFileImage = currentFile.thumbs.url2
				} else {
					that.uploadProgress.currentFileImage = ''
				}

				// 如果是重试，更新状态显示
				if (currentFile.retryCount > 0) {
					currentFile.status = '重试'
					currentFile.statusText = '重试中...'
					that.$set(that.dataList, currentIndex, currentFile)
				}
			}

			// 启动计时器
			that.startUploadTimer()

			that.uploadParams.dataList = that.dataList

			// 发起上传请求
			that.$http.Post("admin/baiduFile/asayncBaiduFile", that.uploadParams, isSingle ? "正在上传..." : "").then(
				res => {
					// 停止计时器
					that.stopUploadTimer()

					let currentIndex = that.uploadParams.startNum - 1
					let newItem = that.dataList[currentIndex]

					// 检查后端返回的状态
					if (res.status === '重复') {
						// 重复的情况
						newItem.status = '重复'
						newItem.statusText = res.msg
						newItem.retryCount = 0
						that.$set(that.dataList, currentIndex, newItem)

						// 更新进度统计
						that.uploadProgress.current++
						that.uploadProgress.duplicate++

						// 移动到下一个文件
						that.uploadParams.startNum = Number(that.uploadParams.startNum) + 1
						console.log('检测到重复内容，跳过到下一个')
					} else if (res.status === '失败') {
						// 检查重试次数
						if (!newItem.retryCount || newItem.retryCount === 0) {
							// 首次失败，标记为将重试
							newItem.retryCount = 1
							newItem.status = '失败'
							newItem.statusText = '失败(将重试)'
							that.$set(that.dataList, currentIndex, newItem)

							console.log('后端返回失败，2秒后重试...')

							if (isSingle == false) {
								// 2秒后重试当前文件
								setTimeout(function () {
									that.confirmAsaync(false)
								}, 2000)
							} else {
								that.resetProgress()
							}
							return
						} else {
							// 第二次失败，最终标记为失败
							newItem.status = '失败'
							newItem.statusText = '重试后仍失败'
							that.$set(that.dataList, currentIndex, newItem)

							// 更新进度
							that.uploadProgress.current++
							that.uploadProgress.failed++

							// 移动到下一个
							that.uploadParams.startNum = Number(that.uploadParams.startNum) + 1
							console.log('后端返回失败且重试后仍失败，跳过到下一个')
						}
					} else {
						// 成功的情况
						newItem.status = res.status
						newItem.statusText = res.msg
						// 重置重试计数
						newItem.retryCount = 0
						that.$set(that.dataList, currentIndex, newItem)

						// 更新进度统计
						that.uploadProgress.current++
						that.uploadProgress.success++

						// 移动到下一个文件
						that.uploadParams.startNum = Number(that.uploadParams.startNum) + 1
					}

					that.$forceUpdate()

					console.log(isSingle)
					if (isSingle == false) {
						// 继续上传下一个
						setTimeout(function () {
							that.confirmAsaync(false)
						}, 2000)
					} else {
						// 单个上传完成后重置进度
						that.resetProgress()
					}
				}).catch(err => {
					console.log(err)
					// 停止计时器
					that.stopUploadTimer()

					let currentIndex = that.uploadParams.startNum - 1
					let newItem = that.dataList[currentIndex]

					// 检查重试次数
					if (!newItem.retryCount || newItem.retryCount === 0) {
						// 首次失败，标记为将重试
						newItem.retryCount = 1
						newItem.status = '失败'
						newItem.statusText = '失败(将重试)'
						that.$set(that.dataList, currentIndex, newItem)

						// 不增加 startNum，不更新进度统计
						console.log('首次失败，2秒后重试...')

						if (isSingle == false) {
							// 2秒后重试当前文件
							setTimeout(function () {
								that.confirmAsaync(false)
							}, 2000)
						} else {
							that.resetProgress()
						}
					} else {
						// 第二次失败，最终标记为失败
						newItem.status = '失败'
						newItem.statusText = '重试后仍失败'
						that.$set(that.dataList, currentIndex, newItem)

						// 更新进度
						that.uploadProgress.current++
						that.uploadProgress.failed++

						// 移动到下一个
						that.uploadParams.startNum = Number(that.uploadParams.startNum) + 1
						console.log('重试后仍失败，跳过到下一个')

						if (isSingle == false) {
							// 继续上传下一个
							setTimeout(function () {
								that.confirmAsaync(false)
							}, 2000)
						} else {
							that.resetProgress()
						}
					}
				})
		},

	}
}
</script>

<style scoped>
/* ==================== 全局容器 ==================== */
.page-container {
	min-height: 100vh;
	padding: 16px;
	background: linear-gradient(135deg, #0a0e27 0%, #1a1f3a 50%, #0f1729 100%);
	font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

/* ==================== 科技卡片 ==================== */
.tech-card {
	background: rgba(26, 31, 58, 0.6);
	backdrop-filter: blur(10px);
	border-radius: 12px;
	padding: 16px;
	margin-bottom: 16px;
	border: 1px solid rgba(0, 240, 255, 0.2);
	box-shadow:
		0 8px 32px rgba(0, 240, 255, 0.1),
		inset 0 1px 0 rgba(255, 255, 255, 0.1);
	transition: all 0.3s ease;
	position: relative;
	overflow: hidden;
}

.tech-card::before {
	content: '';
	position: absolute;
	top: 0;
	left: -100%;
	width: 100%;
	height: 2px;
	background: linear-gradient(90deg, transparent, #00f0ff, transparent);
	animation: scan 3s infinite;
}

@keyframes scan {

	0%,
	100% {
		left: -100%;
	}

	50% {
		left: 100%;
	}
}

.tech-card:hover {
	border-color: rgba(0, 240, 255, 0.4);
}

/* ==================== 卡片标题 ==================== */
.card-title {
	display: flex;
	align-items: center;
	font-size: 16px;
	font-weight: 600;
	color: #00f0ff;
	margin-bottom: 12px;
	padding-bottom: 8px;
	border-bottom: 1px solid rgba(0, 240, 255, 0.2);
	text-shadow: 0 0 10px rgba(0, 240, 255, 0.5);
}

.title-icon {
	margin-right: 6px;
	font-size: 18px;
	filter: drop-shadow(0 0 8px rgba(0, 240, 255, 0.6));
}

.file-count {
	margin-left: auto;
	font-size: 12px;
	color: #7f8ea3;
	font-weight: normal;
	background: rgba(0, 240, 255, 0.1);
	padding: 2px 10px;
	border-radius: 10px;
	border: 1px solid rgba(0, 240, 255, 0.2);
}

/* ==================== 查询区域 ==================== */
.query-content {
	display: flex;
	gap: 12px;
	align-items: center;
}

.path-input {
	flex: 1;
}

/* ==================== 配置区域 ==================== */
.config-row {
	display: flex;
	gap: 12px;
	margin-bottom: 12px;
	flex-wrap: wrap;
}

.config-item {
	flex: 1;
	min-width: 150px;
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.config-item-large {
	flex: 1;
	min-width: 150px;
}

.config-label {
	font-size: 13px;
	color: #7f8ea3;
	font-weight: 500;
	letter-spacing: 0.3px;
}

/* ==================== 按钮组 ==================== */
.button-group {
	display: flex;
	gap: 12px;
	margin-left: auto;
}

/* ==================== 科技输入框 ==================== */
.tech-input {
	width: 100%;
}

.tech-input>>>.el-input__inner {
	background: rgba(10, 14, 39, 0.6) !important;
	border: 1px solid rgba(0, 240, 255, 0.3) !important;
	color: #e0e6ed !important;
	border-radius: 6px;
	padding: 8px 12px;
	font-size: 13px;
	height: 36px;
	transition: all 0.3s ease;
}

.tech-input>>>.el-input__inner:hover {
	border-color: rgba(0, 240, 255, 0.5) !important;
}

.tech-input>>>.el-input__inner:focus {
	border-color: #00f0ff !important;
	box-shadow: 0 0 20px rgba(0, 240, 255, 0.4);
	background: rgba(10, 14, 39, 0.8) !important;
}

.tech-input>>>.el-input__inner::placeholder {
	color: #4a5568;
}

.number-input {
	width: 100%;
}

/* ==================== 科技下拉框 ==================== */
.tech-select {
	width: 100%;
}

.tech-select>>>.el-input__inner {
	background: rgba(10, 14, 39, 0.6) !important;
	border: 1px solid rgba(0, 240, 255, 0.3) !important;
	color: #e0e6ed !important;
	border-radius: 6px;
	height: 36px;
	font-size: 13px;
	transition: all 0.3s ease;
}

.tech-select>>>.el-input__inner:hover {
	border-color: rgba(0, 240, 255, 0.5) !important;
}

.tech-select>>>.el-input__inner:focus {
	border-color: #00f0ff !important;
	box-shadow: 0 0 20px rgba(0, 240, 255, 0.4);
}

.select-large {
	width: 100%;
}

/* ==================== 科技按钮 ==================== */
.tech-button {
	padding: 8px 20px !important;
	border-radius: 6px !important;
	font-weight: 600 !important;
	font-size: 13px !important;
	letter-spacing: 0.3px;
	transition: all 0.3s ease !important;
	border: none !important;
	position: relative;
	overflow: hidden;
	height: 36px;
}

.tech-button::before {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	width: 0;
	height: 0;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.2);
	transform: translate(-50%, -50%);
	transition: width 0.6s, height 0.6s;
}

.tech-button:hover::before {
	display: none;
}

.primary-button {
	background: linear-gradient(135deg, #00f0ff 0%, #0099cc 100%) !important;
	color: #0a0e27 !important;
	box-shadow: 0 4px 15px rgba(0, 240, 255, 0.3);
}

.primary-button:hover {
	box-shadow: 0 6px 25px rgba(0, 240, 255, 0.5);
}

.success-button {
	background: linear-gradient(135deg, #00ff88 0%, #00cc6a 100%) !important;
	color: #0a0e27 !important;
	box-shadow: 0 4px 15px rgba(0, 255, 136, 0.3);
}

.success-button:hover {
	box-shadow: 0 6px 25px rgba(0, 255, 136, 0.5);
}

.warning-button {
	background: linear-gradient(135deg, #ffaa00 0%, #ff8800 100%) !important;
	color: #0a0e27 !important;
	box-shadow: 0 4px 15px rgba(255, 170, 0, 0.3);
}

.warning-button:hover {
	box-shadow: 0 6px 25px rgba(255, 170, 0, 0.5);
}

/* ==================== 表格样式 ==================== */
.tech-table {
	width: 100%;
}

.tech-table>>>.el-table {
	background: transparent !important;
	color: #e0e6ed;
}

.tech-table>>>.el-table::before {
	background: transparent !important;
}

.tech-table>>>.el-table th,
.tech-table>>>.el-table tr {
	background: transparent !important;
}

.tech-table>>>.el-table td,
.tech-table>>>.el-table th.is-leaf {
	border-bottom: 1px solid rgba(0, 240, 255, 0.1) !important;
}

.tech-table>>>.el-table td {
	color: #b8c5d6 !important;
	transition: all 0.3s ease;
	position: relative;
	z-index: 1;
}

.tech-table>>>.el-table__body tr {
	background: rgba(10, 14, 39, 0.3) !important;
	transition: all 0.3s ease;
	border-left: 3px solid transparent;
}

.tech-table>>>.el-table__body tr:hover {
	background: linear-gradient(90deg,
		rgba(0, 240, 255, 0.2) 0%,
		rgba(0, 240, 255, 0.15) 50%,
		rgba(0, 240, 255, 0.05) 100%) !important;
	border-left-color: #00f0ff;
}

.tech-table>>>.el-table__body tr:hover td {
	color: #e0e6ed !important;
}

.tech-table>>>.el-table__body tr.success-row {
	background: rgba(0, 255, 136, 0.1) !important;
}

.tech-table>>>.el-table__body tr.warning-row {
	background: rgba(255, 170, 0, 0.1) !important;
}

.tech-table>>>.el-table__body-wrapper {
	scrollbar-width: thin;
	scrollbar-color: rgba(0, 240, 255, 0.3) rgba(10, 14, 39, 0.5);
}

.tech-table>>>.el-table__body-wrapper::-webkit-scrollbar {
	width: 8px;
	height: 8px;
}

.tech-table>>>.el-table__body-wrapper::-webkit-scrollbar-track {
	background: rgba(10, 14, 39, 0.5);
	border-radius: 4px;
}

.tech-table>>>.el-table__body-wrapper::-webkit-scrollbar-thumb {
	background: rgba(0, 240, 255, 0.3);
	border-radius: 4px;
	transition: background 0.3s;
}

.tech-table>>>.el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
	background: rgba(0, 240, 255, 0.5);
}

/* ==================== 预览图片 ==================== */
.preview-image {
	width: 50px !important;
	height: 50px !important;
	border-radius: 6px;
	border: 2px solid rgba(0, 240, 255, 0.3);
	cursor: pointer;
	transition: all 0.3s ease;
	object-fit: cover;
	position: relative;
}

.preview-image:hover {
	border-color: #00f0ff;
	z-index: 10;
}

/* ==================== 状态标签 ==================== */
.status-tag {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 4px 12px;
	border-radius: 16px;
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.3px;
	border: 1px solid;
	transition: all 0.3s ease;
}

.success-tag {
	background: rgba(0, 255, 136, 0.15);
	color: #00ff88;
	border-color: rgba(0, 255, 136, 0.4);
	box-shadow: 0 0 10px rgba(0, 255, 136, 0.2);
}

.error-tag {
	background: rgba(255, 71, 87, 0.15);
	color: #ff4757;
	border-color: rgba(255, 71, 87, 0.4);
	box-shadow: 0 0 10px rgba(255, 71, 87, 0.2);
}

.warning-tag {
	background: rgba(255, 170, 0, 0.15);
	color: #ffaa00;
	border-color: rgba(255, 170, 0, 0.4);
	box-shadow: 0 0 10px rgba(255, 170, 0, 0.2);
}

.timeout-tag {
	background: rgba(138, 43, 226, 0.15);
	color: #bb86fc;
	border-color: rgba(138, 43, 226, 0.4);
	box-shadow: 0 0 10px rgba(138, 43, 226, 0.2);
}

.retry-tag {
	background: rgba(0, 240, 255, 0.15);
	color: #00f0ff;
	border-color: rgba(0, 240, 255, 0.4);
	box-shadow: 0 0 10px rgba(0, 240, 255, 0.2);
	animation: retry-pulse 1.5s ease-in-out infinite;
}

@keyframes retry-pulse {
	0%, 100% {
		opacity: 1;
	}
	50% {
		opacity: 0.6;
	}
}

.duplicate-tag {
	background: rgba(147, 51, 234, 0.15);
	color: #9333ea;
	border-color: rgba(147, 51, 234, 0.4);
	box-shadow: 0 0 10px rgba(147, 51, 234, 0.2);
	animation: duplicate-glow 2s ease-in-out infinite;
}

@keyframes duplicate-glow {
	0%, 100% {
		box-shadow: 0 0 10px rgba(147, 51, 234, 0.2);
	}
	50% {
		box-shadow: 0 0 20px rgba(147, 51, 234, 0.4);
	}
}

.default-tag {
	background: rgba(127, 142, 163, 0.15);
	color: #7f8ea3;
	border-color: rgba(127, 142, 163, 0.4);
}

/* ==================== 操作按钮 ==================== */
.action-button {
	color: #00f0ff !important;
	font-weight: 600 !important;
	padding: 8px 20px !important;
	transition: all 0.3s ease !important;
	position: relative;
	background: transparent !important;
	border-radius: 4px;
}

.action-button::before {
	content: '';
	position: absolute;
	left: 50%;
	top: 50%;
	width: 0;
	height: 0;
	background: rgba(0, 240, 255, 0.2);
	border-radius: 50%;
	transform: translate(-50%, -50%);
	transition: width 0.4s ease, height 0.4s ease;
}

.action-button:hover {
	color: #00ff88 !important;
	background: rgba(0, 240, 255, 0.1) !important;
}

.action-button:hover::before {
	display: none;
}

/* 表格行悬浮时的操作按钮 */
.tech-table>>>.el-table__body tr:hover .action-button {
	color: #00f0ff !important;
}

/* ==================== 响应式 ==================== */
@media (max-width: 1200px) {
	.config-row {
		flex-direction: column;
	}

	.config-item,
	.config-item-large {
		min-width: 100%;
	}
}

@media (max-width: 768px) {
	.page-container {
		padding: 12px;
	}

	.tech-card {
		padding: 12px;
		margin-bottom: 12px;
	}

	.query-content {
		flex-direction: column;
	}

	.path-input {
		width: 100%;
	}

	.button-group {
		flex-direction: column;
	}
}

/* ==================== Element UI 深色主题覆盖 ==================== */
.tech-table>>>.el-table__empty-text {
	color: #7f8ea3 !important;
}

.tech-table>>>.el-table__fixed-right::before,
.tech-table>>>.el-table__fixed::before {
	background: transparent !important;
}

/* 修复固定列的对齐问题 */
.tech-table>>>.el-table__fixed,
.tech-table>>>.el-table__fixed-right {
	background: rgba(10, 14, 39, 0.95) !important;
	box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
}

.tech-table>>>.el-table__fixed-right {
	right: 0 !important;
}

/* 固定列的表头样式 */
.tech-table>>>.el-table__fixed-header-wrapper th,
.tech-table>>>.el-table__fixed-right .el-table__fixed-header-wrapper th {
	background: rgba(26, 31, 58, 0.95) !important;
	color: #00f0ff !important;
	font-weight: bold;
}

/* 固定列的行样式 */
.tech-table>>>.el-table__fixed .el-table__body tr,
.tech-table>>>.el-table__fixed-right .el-table__body tr {
	background: rgba(10, 14, 39, 0.3) !important;
}

.tech-table>>>.el-table__fixed .el-table__body tr:hover,
.tech-table>>>.el-table__fixed-right .el-table__body tr:hover {
	background: rgba(0, 240, 255, 0.15) !important;
}

/* 修复滚动条导致的对齐 */
.tech-table>>>.el-table__header-wrapper {
	overflow: hidden !important;
}

.tech-table>>>.el-table__body-wrapper {
	overflow-y: auto !important;
	overflow-x: auto !important;
}

/* 下拉菜单深色样式 */
.el-select-dropdown {
	background: rgba(26, 31, 58, 0.95) !important;
	border: 1px solid rgba(0, 240, 255, 0.3) !important;
	box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5) !important;
}

.el-select-dropdown__item {
	color: #e0e6ed !important;
	background: transparent !important;
}

.el-select-dropdown__item:hover {
	background: rgba(0, 240, 255, 0.2) !important;
}

.el-select-dropdown__item.selected {
	color: #00f0ff !important;
	font-weight: 600;
}

/* ==================== 进度弹窗样式 ==================== */
.progress-dialog>>>.el-dialog {
	background: linear-gradient(135deg, rgba(26, 31, 58, 0.98) 0%, rgba(15, 23, 41, 0.98) 100%) !important;
	border: 2px solid rgba(0, 240, 255, 0.3);
	border-radius: 16px;
	box-shadow: 0 20px 60px rgba(0, 0, 0, 0.8), 0 0 40px rgba(0, 240, 255, 0.2);
}

.progress-dialog>>>.el-dialog__header {
	background: linear-gradient(90deg, rgba(0, 240, 255, 0.15) 0%, transparent 100%);
	border-bottom: 1px solid rgba(0, 240, 255, 0.3);
	padding: 20px;
}

.progress-dialog>>>.el-dialog__title {
	color: #00f0ff !important;
	font-size: 20px;
	font-weight: 700;
	text-shadow: 0 0 10px rgba(0, 240, 255, 0.5);
}

.progress-dialog>>>.el-dialog__headerbtn .el-dialog__close {
	color: #00f0ff !important;
	font-size: 20px;
}

.progress-dialog>>>.el-dialog__headerbtn:hover .el-dialog__close {
	color: #00ff88 !important;
}

.progress-dialog>>>.el-dialog__body {
	padding: 24px;
}

.progress-container {
	display: flex;
	flex-direction: column;
	gap: 24px;
}

/* 进度条区域 */
.progress-section {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.section-title {
	font-size: 14px;
	color: #7f8ea3;
	font-weight: 600;
	margin-bottom: 8px;
}

.progress-text {
	text-align: center;
	color: #e0e6ed;
	font-size: 14px;
	font-weight: 600;
	margin-top: 8px;
}

/* Element UI进度条样式覆盖 */
.progress-dialog>>>.el-progress-bar__outer {
	background: rgba(10, 14, 39, 0.6) !important;
	border: 1px solid rgba(0, 240, 255, 0.2);
}

.progress-dialog>>>.el-progress-bar__inner {
	background: linear-gradient(90deg, #00f0ff 0%, #00cc99 100%) !important;
	box-shadow: 0 0 20px rgba(0, 240, 255, 0.6);
}

.progress-dialog>>>.el-progress__text {
	color: #0a0e27 !important;
	font-weight: 700 !important;
}

/* 统计信息区域 */
.stats-section {
	display: flex;
	gap: 16px;
	justify-content: space-around;
}

.stat-item {
	flex: 1;
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 16px;
	border-radius: 10px;
	border: 1px solid;
	transition: all 0.3s ease;
}

.stat-icon {
	font-size: 28px;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 50px;
	height: 50px;
	border-radius: 50%;
	font-weight: bold;
}

.stat-content {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.stat-label {
	font-size: 12px;
	opacity: 0.8;
	font-weight: 600;
}

.stat-value {
	font-size: 24px;
	font-weight: 700;
}

.success-stat {
	background: rgba(0, 255, 136, 0.1);
	border-color: rgba(0, 255, 136, 0.3);
}

.success-stat .stat-icon {
	background: rgba(0, 255, 136, 0.2);
	color: #00ff88;
}

.success-stat .stat-label,
.success-stat .stat-value {
	color: #00ff88;
}

.duplicate-stat {
	background: rgba(147, 51, 234, 0.1);
	border-color: rgba(147, 51, 234, 0.3);
}

.duplicate-stat .stat-icon {
	background: rgba(147, 51, 234, 0.2);
	color: #9333ea;
}

.duplicate-stat .stat-label,
.duplicate-stat .stat-value {
	color: #9333ea;
}

.failed-stat {
	background: rgba(255, 71, 87, 0.1);
	border-color: rgba(255, 71, 87, 0.3);
}

.failed-stat .stat-icon {
	background: rgba(255, 71, 87, 0.2);
	color: #ff4757;
}

.failed-stat .stat-label,
.failed-stat .stat-value {
	color: #ff4757;
}

.timeout-stat {
	background: rgba(255, 170, 0, 0.1);
	border-color: rgba(255, 170, 0, 0.3);
}

.timeout-stat .stat-icon {
	background: rgba(255, 170, 0, 0.2);
	color: #ffaa00;
}

.timeout-stat .stat-label,
.timeout-stat .stat-value {
	color: #ffaa00;
}

/* 当前上传区域 */
.current-upload-section {
	background: rgba(0, 240, 255, 0.05);
	border: 1px solid rgba(0, 240, 255, 0.2);
	border-radius: 10px;
	padding: 16px;
}

.current-file-wrapper {
	display: flex;
	gap: 16px;
	align-items: flex-start;
}

.current-file-image {
	flex-shrink: 0;
}

.course-thumbnail {
	width: 150px !important;
	height: 150px !important;
	border-radius: 10px;
	border: 2px solid rgba(0, 240, 255, 0.4);
	box-shadow: 0 4px 20px rgba(0, 240, 255, 0.3);
	cursor: pointer;
	transition: all 0.3s ease;
}

.course-thumbnail:hover {
	border-color: #00f0ff;
	box-shadow: 0 6px 30px rgba(0, 240, 255, 0.5);
	transform: scale(1.02);
}

.current-file {
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.file-name {
	color: #e0e6ed;
	font-size: 14px;
	font-weight: 600;
	word-break: break-all;
	padding: 8px 12px;
	background: rgba(0, 240, 255, 0.1);
	border-radius: 6px;
	border-left: 3px solid #00f0ff;
}

.upload-timer {
	display: flex;
	flex-direction: column;
	gap: 8px;
	padding: 12px;
	background: rgba(10, 14, 39, 0.6);
	border-radius: 8px;
	border: 1px solid rgba(0, 240, 255, 0.2);
	transition: all 0.3s ease;
}

.upload-timer.near-timeout {
	border-color: rgba(255, 170, 0, 0.5);
	background: rgba(255, 170, 0, 0.1);
	animation: pulse 1.5s ease-in-out infinite;
}

.upload-timer.timeout-warning {
	border-color: rgba(255, 71, 87, 0.5);
	background: rgba(255, 71, 87, 0.1);
	animation: pulse-fast 0.8s ease-in-out infinite;
}

@keyframes pulse {
	0%, 100% {
		box-shadow: 0 0 0 0 rgba(255, 170, 0, 0.4);
	}
	50% {
		box-shadow: 0 0 20px 5px rgba(255, 170, 0, 0.2);
	}
}

@keyframes pulse-fast {
	0%, 100% {
		box-shadow: 0 0 0 0 rgba(255, 71, 87, 0.4);
	}
	50% {
		box-shadow: 0 0 20px 5px rgba(255, 71, 87, 0.2);
	}
}

.timer-label {
	font-size: 12px;
	color: #7f8ea3;
	font-weight: 600;
}

.timer-value {
	font-size: 32px;
	color: #00f0ff;
	font-weight: 700;
	font-family: 'Courier New', monospace;
	text-align: center;
	text-shadow: 0 0 10px rgba(0, 240, 255, 0.5);
}

.near-timeout .timer-value {
	color: #ffaa00;
	text-shadow: 0 0 10px rgba(255, 170, 0, 0.5);
}

.timeout-warning .timer-value {
	color: #ff4757;
	text-shadow: 0 0 10px rgba(255, 71, 87, 0.5);
}

.timer-bar {
	height: 6px;
	background: rgba(10, 14, 39, 0.8);
	border-radius: 3px;
	overflow: hidden;
	border: 1px solid rgba(0, 240, 255, 0.3);
}

.timer-bar-fill {
	height: 100%;
	background: linear-gradient(90deg, #00f0ff 0%, #00cc99 100%);
	transition: width 1s linear;
	box-shadow: 0 0 10px rgba(0, 240, 255, 0.6);
}

.near-timeout .timer-bar-fill {
	background: linear-gradient(90deg, #ffaa00 0%, #ff8800 100%);
	box-shadow: 0 0 10px rgba(255, 170, 0, 0.6);
}

.timeout-warning .timer-bar-fill {
	background: linear-gradient(90deg, #ff4757 0%, #ff2233 100%);
	box-shadow: 0 0 10px rgba(255, 71, 87, 0.6);
}

.timeout-hint {
	margin-top: 12px;
	padding: 10px;
	background: rgba(255, 170, 0, 0.15);
	border: 1px solid rgba(255, 170, 0, 0.4);
	border-radius: 6px;
	color: #ffaa00;
	font-size: 13px;
	font-weight: 600;
	text-align: center;
	animation: blink 1s ease-in-out infinite;
}

@keyframes blink {
	0%, 100% {
		opacity: 1;
	}
	50% {
		opacity: 0.6;
	}
}
</style>